package com.qt.leetcode;

import org.apache.commons.lang3.ArrayUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Demo04 {

    public static void main(String[] args) {
        int[] a = {1,2};
        int[] b = {3,4};
        double medianSortedArrays = findMedianSortedArrays2(a, b);
        System.out.println(medianSortedArrays);

    }

    public static double findMedianSortedArrays3(int[] nums1, int[] nums2) {

        if (nums1.length > nums2.length) {
            return findMedianSortedArrays(nums2, nums1);
        }

        int m = nums1.length;
        int n = nums2.length;
        int left = 0, right = m;
        // median1：前一部分的最大值
        // median2：后一部分的最小值
        int median1 = 0, median2 = 0;

        while (left <= right) {
            // 前一部分包含 nums1[0 .. i-1] 和 nums2[0 .. j-1]
            // 后一部分包含 nums1[i .. m-1] 和 nums2[j .. n-1]
            int i = (left + right) / 2;//i 和   j分别代表 第一个数组和第二个数组的指针位置
            int j = (m + n + 1) / 2 - i;

            // nums_im1, nums_i, nums_jm1, nums_j 分别表示 nums1[i-1], nums1[i], nums2[j-1], nums2[j]
            int nums_im1 = (i == 0 ? Integer.MIN_VALUE : nums1[i - 1]);
            int nums_i = (i == m ? Integer.MAX_VALUE : nums1[i]);
            int nums_jm1 = (j == 0 ? Integer.MIN_VALUE : nums2[j - 1]);
            int nums_j = (j == n ? Integer.MAX_VALUE : nums2[j]);

            if (nums_im1 <= nums_j) {
                median1 = Math.max(nums_im1, nums_jm1);
                median2 = Math.min(nums_i, nums_j);
                left = i + 1;//左边的长度加1
            } else {
                right = i - 1;//右边的长度减1
            }
        }

        return (m + n) % 2 == 0 ? (median1 + median2) / 2.0 : median1;

    }

    public static double findMedianSortedArrays2(int[] nums1, int[] nums2) {

        if(nums1.length > nums2.length){
            //将长度短的数组排前面
            int[] temp = nums1;
            nums1 = nums2;
            nums2 = temp;
        }

        int m = nums1.length,n = nums2.length;

        //分割线左边元素个数 n + (n - m + 1)/2
        int totalleft = (m + n + 1) / 2;
        //再 nums1 中[0,m]找分割线
        //使得 nums1[i - 1] <= nums2[j] && nums2[j - 1] <= nums1[i]  第一个左边 小于第二个右边
        int left = 0,right = m;
        while (left < right){
            // 前一部分包含 nums1[0 .. i-1] 和 nums2[0 .. j-1]
            // 后一部分包含 nums1[i .. m-1] 和 nums2[j .. n-1]

            int i = (left + right + 1)/2;
            int j = totalleft - i;
            if(nums1[i - 1] > nums2[j]){
                right = i -1;
            }else {
                left = i;
            }
        }

        int i = left;
        int j = totalleft - i;
        int nums1LeftMax = i == 0 ? Integer.MIN_VALUE : nums1[i - 1];
        int nums1RightMin = i == m ? Integer.MAX_VALUE : nums1[i];
        int nums2LeftMax = j == 0 ? Integer.MIN_VALUE : nums2[j - 1];
        int muns2RightMin = j == n ? Integer.MAX_VALUE : nums2[j];

        if(((m + n) % 2) == 1){
            return Math.max(nums1LeftMax, nums2LeftMax);
        }else {
            return (double) (Math.max(nums1LeftMax,nums2LeftMax) + Math.min(nums1RightMin, muns2RightMin)) /2;
        }

    }


    public static double findMedianSortedArrays(int[] nums1, int[] nums2) {

        int[] res = ArrayUtils.addAll(nums1, nums2);
        List<Integer> collect = Arrays.stream(res)
                .distinct()
                .sorted()
                .boxed()//装箱操作
                .collect(Collectors.toList());
        double item = 0D;
        if(collect.size() % 2 == 0){
            item = Double.valueOf(collect.get(collect.size() / 2) + collect.get((collect.size() / 2) - 1)) / 2;
        }else {
            item = collect.get(((collect.size() + 1) / 2) - 1);
        }


        return item;

    }

}
